#pragma once

#include <d3d9.h>
#include <d3dx9.h>

class Transform3D {
private:
	D3DXVECTOR3 pos;
	D3DXVECTOR3 rot;
	D3DXVECTOR3 scl;
public:
	Transform3D();
	Transform3D(const D3DXVECTOR3& position);
	Transform3D(float x, float y, float z);
	Transform3D(const D3DXVECTOR3& position, const D3DXVECTOR3& rotation);
	Transform3D(float x, float y, float z, float xRotation, float yRotation, float zRotation);
	Transform3D(const D3DXVECTOR3& position, const D3DXVECTOR3& rotation, const D3DXVECTOR3& scale);
	Transform3D(float x, float y, float z, float xRotation, float yRotation, float zRotation, float xScale, float yScale, float zScale);
	~Transform3D();

	/*
	Get the position of the Transform.
	@param	out			Vector to store the data in.
	*/
	void GetPosition(D3DXVECTOR3& out) {
		out.x = pos.x;
		out.y = pos.y;
		out.z = pos.z;
		return;
	}
	/*
	Get the position of the Transform.
	@param	out			Vector to store the data in.
	*/
	void GetPosition(D3DXVECTOR4& out) {
		out.x = pos.x;
		out.y = pos.y;
		out.z = pos.z;
		out.w = 1.f;
		return;
	}
	/*
	@return	Position in x.
	*/
	float GetX() { return pos.x; }
	/*
	@return Position in y.
	*/
	float GetY() { return pos.y; }
	/*
	@return	Position in z.
	*/
	float GetZ() { return pos.z; }
	/*
	Get the rotation of the transform.
	@parma	out			Vector to store the data in.
	*/
	void GetRotation(D3DXVECTOR3& out) {
		out.x = rot.x;
		out.y = rot.y;
		out.z = rot.z;
		return;
	}
	/*
	@return	Rotation around the x axis.
	*/
	float GetRotationX() { return rot.x; }
	/*
	@return	Rotation around the y axis.
	*/
	float GetRotationY() { return rot.y; }
	/*
	@return	Rotation around the z axis.
	*/
	float GetRotationZ() { return rot.z; }
	/*
	Get the scale of the Transform.
	@param	out			Vector to store the data in.
	*/
	void GetScale(D3DXVECTOR3& out) {
		out.x = scl.x;
		out.y = scl.y;
		out.z = scl.z;
		return;
	}
	/*
	@return	Scale in x.
	*/
	float GetScaleX() { return scl.x; }
	/*
	@return	Scale in y.
	*/
	float GetScaleY() { return scl.y; }
	/*
	@return	Scale in z.
	*/
	float GetScaleZ() { return scl.z; }

	/*
	Get the translation matrix for the Transform.
	@param	out			Matrix to store the data in.
	*/
	void MatrixTranslation(D3DXMATRIX& out) {
		D3DXMatrixTranslation(&out, pos.x, pos.y, pos.z);
		return;
	}
	/*
	Get the rotation matrix for the Transform.
	@param	out			Matrix to store the data in.
	*/
	void MatrixRotation(D3DXMATRIX& out) {
		D3DXMATRIX rx, ry, rz;
		D3DXMatrixRotationX(&rx, rot.x);
		D3DXMatrixRotationY(&ry, rot.y);
		D3DXMatrixRotationZ(&rz, rot.z);
		out = rx * ry * rz;
		return;
	}
	/*
	Get the scale matrix for the Transform.
	@param	out			Matrix to store the data in.
	*/
	void MatrixScale(D3DXMATRIX& out) {
		D3DXMatrixScaling(&out, scl.x, scl.y, scl.z);
		return;
	}

	/*
	Override the position with a new one.
	@param	position	New position.
	*/
	void SetPosition(const D3DXVECTOR3& position) {
		SetPosition(position.x, position.y, position.z);
		return;
	}
	/*
	Override the position with a new one.
	@param	xPosition	New position in x.
	@param	yPosition	New position in y.
	@param	zPosition	New position in z.
	*/
	void SetPosition(float xPosition, float yPosition, float zPosition) {
		SetPositionX(xPosition);
		SetPositionY(yPosition);
		SetPositionZ(zPosition);
		return;
	}
	/*
	Override the position in x with a new one.
	@param	xPosition	New position in x.
	*/
	void SetPositionX(float xPosition) {
		pos.x = xPosition;
		return;
	}
	/*
	Override the position in y with a new one.
	@param	yPosition	New position in y.
	*/
	void SetPositionY(float yPosition) {
		pos.y = yPosition;
		return;
	}
	/*
	Override the position in z with a new one.
	@param	zPosition	New position in z.
	*/
	void SetPositionZ(float zPosition) {
		pos.z = zPosition;
		return;
	}
	/*
	Override the rotation with a new one.
	@param	rotation	New rotation.
	*/
	void SetRotation(const D3DXVECTOR3& rotation) {
		SetPosition(rotation.x, rotation.y, rotation.z);
		return;
	}
	/*
	Override the rotation with a new one.
	@param	xRotation	New rotation in x.
	@param	yRotation	New rotation in y.
	@param	zRotation	New rotation in z.
	*/
	void SetRotation(float xRotation, float yRotation, float zRotation) {
		SetPositionX(xRotation);
		SetPositionY(yRotation);
		SetPositionZ(zRotation);
		return;
	}
	/*
	Override the rotation in x with a new one.
	@param	xRotation	New rotation in x.
	*/
	void SetRotationX(float xRotation) {
		rot.x = xRotation;
		return;
	}
	/*
	Override the rotation in y with a new one.
	@param	yRotation	New rotation in y.
	*/
	void SetRotationY(float yRotation) {
		rot.y = yRotation;
		return;
	}
	/*
	Override the rotation in z with a new one.
	@param	zRotation	New rotation in z.
	*/
	void SetRotationZ(float zRotation) {
		rot.z = zRotation;
		return;
	}
	/*
	Override the scale with a new one.
	@param	scale		New scale.
	*/
	void SetScale(const D3DXVECTOR3& scale) {
		SetScale(scale.x, scale.y, scale.z);
		return;
	}
	/*
	Override the scale with a new one.
	@param	xScale		New scale in x.
	@param	yScale		New scale in y.
	@param	zScale		New scale in z.
	*/
	void SetScale(float xScale, float yScale, float zScale) {
		SetScaleX(xScale);
		SetScaleY(yScale);
		SetScaleZ(zScale);
		return;
	}
	/*
	Override the scale in x with a new one.
	@param	xScale		New scale in x.
	*/
	void SetScaleX(float xScale) {
		scl.x = xScale;
		return;
	}
	/*
	Override the scale in y with a new one.
	@param	yScale		New scale in y.
	*/
	void SetScaleY(float yScale) {
		scl.y = yScale;
		return;
	}
	/*
	Override the scale in y with a new one.
	@param	zScale		New scale in z.
	*/
	void SetScaleZ(float zScale) {
		scl.z = zScale;
		return;
	}
};

